﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace DataConsistency.UC
{
    public partial class ThongTinMU : UserControl
    {
        Init GTKhoiTao = new Init();
        Para CPara = new Para();

        public List<Init.MUNOde> listOfNode = new List<Init.MUNOde>();

        private string _defaultPath = "";
        private string _channel ;
        private string _radioPro ;
        private string _networkInter ;
        private string _macType ;
        private string _antene ;
        private string _interfaceQueue ;
        private string _linkLayer;
        private string _routingPro ;
        private int _maxPacket;
        private int _numOfBS = 1;
        private double _stop = 7000;
        private int _attri;
        private int _numClient_Inf;
        private double _bandwidth_down ;
        private double _bandwidth_up ;
        private int _Energy ;
        private int _bSize ;
        private int _periodBroadcast;
        private int _numOfNode;
        public int attri = 1;
        public int soMUMatKetNoi = 10;
        public Random rand = new Random();

        public List<string> listDLPath = new List<string>();
        public List<string> listDLPath1 = new List<string>(); // De ghi file TCL

        #region GetAndSet
        public string Channel
        {
            get { return _channel; }
            set { this._channel = value; }
        }
        public string Radio
        {
            get { return _radioPro; }
            set { this._radioPro = value; }
        }
        public string NetworkInter
        {
            get { return _networkInter; }
            set { this._networkInter = value; }
        }
        public string MacType
        {
            get { return _macType; }
            set { this._macType = value; }
        }
        public string Antene
        {
            get { return _antene; }
            set { this._antene = value; }
        }
        public string InterfaceQueue
        {
            get { return _interfaceQueue; }
            set { this._interfaceQueue = value; }
        }
        public string LinkLayer
        {
            get { return _linkLayer; }
            set { this._linkLayer = value; }
        }
        public string RoutingPro
        {
            get { return _routingPro; }
            set { this._routingPro = value; }
        }
        public int MaxPacket
        {
            get { return _maxPacket; }
            set { this._maxPacket = value; }
        }
        public int NumOfBS
        {
            get { return _numOfBS; }
            set { this._numOfBS = value; }
        }
        public double Stop
        {
            get { return _stop; }
            set { this._stop = value; }
        }
        public int Attri
        {
            get { return _attri; }
            set { this._attri = value; }
        }
        public int NumClientInf
        {
            get { return _numClient_Inf; }
            set { this._numClient_Inf = value; }
        }
        public double BandWidthDown
        {
            get { return _bandwidth_down; }
            set { this._bandwidth_down = value; }
        }
        public double BandWidthUp
        {
            get { return _bandwidth_up; }
            set { this._bandwidth_up = value; }
        }
        public int Energy
        {
            get { return _Energy; }
            set { this._Energy = value; }
        }
        public int BSize
        {
            get { return _bSize; }
            set { this._bSize = value; }
        }
        public int PeriodBroadcast
        {
            get { return _periodBroadcast; }
            set { this._periodBroadcast = value; }
        }
        public string DefaultPath
        {
            get
            {
                return this._defaultPath;
            }
            set
            {
                this._defaultPath = value;
            }
        }
        public int NumOfNode
        {
            get
            {
                return this._numOfNode;
            }
            set
            {
                this._numOfNode = value;
            }
        }
        #endregion
        


        public ThongTinMU()
        {
            InitializeComponent();
        }

        private void cmbnumOfNode_EditValueChanged(object sender, EventArgs e)
        {
            listOfNode.Clear();

            gridNodes.Rows.Clear();  
            GTKhoiTao.INumOfMUs = (int)cmbnumOfNode.Value;
            Random rand = new Random(); // Khoi tao random

            //Duyet qua tung node
            for (int i = 0; i < GTKhoiTao.INumOfMUs; i++)
            {
                string id_item = "node_(" + (i + 1).ToString() + ")";
                double x = rand.Next(1, 1000);
                double y = rand.Next(1, 1000);

                gridNodes.Rows.Add();
                gridNodes.Rows[i].Cells[0].Value = id_item;
                gridNodes.Rows[i].Cells[1].Value = x;
                gridNodes.Rows[i].Cells[2].Value = y;
                /*
                Init.MUNOde muNode = new Init.MUNOde();
                muNode.x = x;
                muNode.y = y;
                listOfNode.Add(muNode);
                 */ 
            }
            updateListOfNode();
            NumOfNode = GTKhoiTao.INumOfMUs;
        }

        public void updateListOfNode()
        {
            listOfNode.Clear();
            //Duyet qua tung node
            for (int i = 0; i < GTKhoiTao.INumOfMUs; i++)
            {
                Init.MUNOde muNode = new Init.MUNOde();
                muNode.id = (string)gridNodes.Rows[i].Cells[0].Value;
                muNode.x = (double)gridNodes.Rows[i].Cells[1].Value;
                muNode.y = (double)gridNodes.Rows[i].Cells[2].Value;
                listOfNode.Add(muNode);
            }
        }

        public void RanDomSoMUMatKetNoi(int limit)
        {
            soMUMatKetNoi = rand.Next(4, limit);
        }
        public void RanDomBS()
        {
            Random rand = new Random();
            double x = rand.Next(300, 700);
            double y = rand.Next(300, 700);
            txtBSX.Text = x.ToString();
            txtBSY.Text = y.ToString();
        }

        //Lay du lieu tu DuLieuThuNghiem
        public void getDuLieu(List<string> listPath)
        {
            this.listDLPath = listPath;
        }

        public void ConvertPathTCL()
        {
            // Doi Path de ghi file TCL
            for (int i = 0; i < listDLPath.Count(); i++)
            {
                string pth = listDLPath[i];
                pth = pth.Replace("\\", "\\\\");
                listDLPath1.Add(pth);
            }
        }
        /// <summary>
        /// Kiem tra Id du lieu co trong list ko
        /// </summary>
        /// <param name="l"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool CheckInList(List<int> l, int t)
        {
            bool flag = false;
            for (int i = 0; i < l.Count; i++)
            {
                if (t == l[i])
                    flag = true;
            }
            return flag;
        }

        public void ThongTinMU_Load(object sender, EventArgs e)
        {
            /*
            if (listDLPath.Count > 0)
            {
                for (int i = 0; i < listDLPath.Count; i++)
                {
                    MessageBox.Show(listDLPath[i].ToString());
                }
            }
            */
 
            // Khoi tao gia tri
            cmbnumOfNode.Value = 40;            
            cmbChannel.Text = "Channel/WirelessChannel" ;
            cmbRadio.Text = "Propagation/TwoRayGround";
            cmbNetwork.Text = "Phy/WirelessPhy";
            cmbMac.Text = "Mac/802_11";
            cmbAntenna.Text = "Antenna/OmniAntenna";
            cmbInterface.Text = "Queue/DropTail/PriQueue";
            cmbLink.Text = "LL";
            cmbRouting.Text = "DSDV" ;
            cmbMaxPacket.Text = "50";
            cmbBandwidthDown.Text = "12500";
            cmbBandwidthUp.Text = "2400";
            cmbEnergy.Text = "1";
            cmbBSize.Text = "512";
            cmbPeriod.Text = "100";
            RanDomBS();
            RanDomSoMUMatKetNoi(12);
        }

        /// <summary>
        /// Lay toa do cua BS
        /// </summary>
        /// <returns></returns>
        public int GetBSX()
        {
            return (int.Parse(txtBSX.Text));
        }
        public int GetBSY()
        {
            return (int.Parse(txtBSY.Text));
        }

        /// <summary>
        /// Random vi tri cua BS
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void btnRefresh_Click(object sender, EventArgs e)
        {
            RanDomBS();
        }

        /// <summary>
        /// Chinh duong dan mac dinh 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void btnPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); 
            folderBrowser.Description = "Select Chase 6 Installation Folder";          
            folderBrowser.RootFolder = Environment.SpecialFolder.Desktop;          
            folderBrowser.ShowNewFolderButton = true;           
        
            if (folderBrowser.ShowDialog(this) == DialogResult.OK)          
            {              
                string pt = folderBrowser.SelectedPath;
                txtPath.Text = pt;
                pt = pt.Replace("\\" , "\\\\");
                //MessageBox.Show(pt);
                this._defaultPath = pt;
            } 
        }

        /// <summary>
        /// Gan cac bien ban dau
        /// </summary>
        public void SetVariable()
        {
            this.Channel = cmbChannel.Text.ToString() ;
            this.Radio = cmbRadio.Text.ToString();
            NetworkInter = cmbNetwork.Text.ToString();
            MacType = cmbMac.Text.ToString();
            Antene = cmbAntenna.Text.ToString();
            InterfaceQueue = cmbInterface.Text.ToString();
            MaxPacket = int.Parse(cmbMaxPacket.Text.ToString());
            LinkLayer = cmbLink.Text.ToString();
            NumOfNode = int.Parse(cmbnumOfNode.Text.ToString());
            RoutingPro = cmbRouting.Text.ToString();
            BandWidthDown = double.Parse(cmbBandwidthDown.Text.ToString());
            BandWidthUp = double.Parse(cmbBandwidthUp.Text.ToString());
            Energy = int.Parse(cmbEnergy.Text.ToString());
            BSize = int.Parse(cmbBSize.Text.ToString());
            PeriodBroadcast = int.Parse(cmbPeriod.Text.ToString());

        }

        /// <summary>
        /// Xuat file TCL
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void btnXuatFile_Click(object sender, EventArgs e)
        {
            SetVariable();
            ConvertPathTCL();

            // =============== Ghi file TCL ============================
            // Define
            string content = "";
            content = content + "# Define options" + "\n";
            content = content + "set val(chan)" + "\t\t" + Channel + "\n" +
                        "set val(prop)" + "\t\t" + Radio + "\n" +
                        "set val(netif)" + "\t\t" + NetworkInter + "\n" +
                        "set val(mac)" + "\t\t" + MacType + "\n" +
                        "set val(ant)" + "\t\t" + Antene + "\n" +
                        "set val(ifq)" + "\t\t" + InterfaceQueue + "\n" +
                        "set val(ifqlen)" + "\t\t" + MaxPacket.ToString() + "\n" +
                        "set val(ll)" + "\t\t\t" + LinkLayer + "\n" +
                        "set val(nn)" + "\t\t\t" + NumOfNode.ToString() + "\n" +
                        "set val(rp)" + "\t\t\t" + RoutingPro + "\n" +
                        "set numBS" + "\t\t\t" + NumOfBS + "\n" +
                        "set val(stop)" + "\t\t" + String.Format("{0:0.0}", _stop) + "\n\n";

            content = content + "#============================" + "\n\n";

            // Hieu chinh ban kinh Broadcast
            content = content + "# === Hieu chinh ban kinh ===" + "\n";
            content = content + "$val(netif) set CPThresh_ 10.0" + "\n" +
                                "$val(netif) set CSThresh_ 1.559e-11" + "\n" +
                                "$val(netif) set RXThresh_ 1.15126e-10" + "\n" +
                                "$val(netif) set Rb_ 2*1e6" + "\n" +
                                "$val(netif) set Pt_ 0.2818" + "\n" +
                                "$val(netif) set freq_ 914e+6" + "\n" +
                                "$val(netif) set L_ 1.0" + "\n\n";

            content = content + "#============================" + "\n\n";

            //Main program
            content = content + "#=== Main Program ===" + "\n";
            content = content + "set ns_ [new Simulator]" + "\n" +
                                "#====================" + "\n\n" +
                                "set tracefd [open out.tr w]" + "\n" +
                                "$ns_ trace-all $tracefd" + "\n\n";

            content = content + "#============================" + "\n\n";

            //Tao ranh gioi mo phong
            content = content + "#Tao ranh gioi mo phong" + "\n";
            content = content + "set topo [new Topography]" + "\n" +
                                "$topo load_flatgrid 1000 1000" + "\n\n";

            content = content + "#============================" + "\n\n";

            //Create-god doi tuong
            content = content + "#Create God doi tuong quan ly cac doi tuong ns-2" + "\n" +
                                "create-god [expr $val(nn) + $numBS]" + "\n" +
                                "set chan_1_ [new $val(chan)]" + "\n";

            content = content + "#============================" + "\n\n";

            // Cau hinh mobile node
            content = content + "#Tao cau hinh mobile node" + "\n" +
                                "Agent/Protoname set numberClient $val(nn)" + "\n" +
                                "Agent/Protoname set bandwidth_down " + BandWidthDown.ToString() + "\n" +
                                "Agent/Protoname set bandwidth_up " + BandWidthUp.ToString() + "\n" +
                                "Agent/Protoname set Energy " + Energy.ToString() + "\n" +
                                "Agent/Protoname set bSize " + BSize.ToString() + "\n" +
                                "Agent/Protoname set period_broadcast " + PeriodBroadcast.ToString() + "\n" +
                                "$ns_ node-config -adhocRouting $val(rp) \\" + "\n" +
                                "\t\t\t\t -llType $val(ll) \\" + "\n" +
                                "\t\t\t\t -macType $val(mac) \\" + "\n" +
                                "\t\t\t\t -ifqType $val(ifq) \\" + "\n" +
                                "\t\t\t\t -ifqLen $val(ifqlen) \\" + "\n" +
                                "\t\t\t\t -antType $val(ant) \\" + "\n" +
                                "\t\t\t\t -propType $val(prop) \\" + "\n" +
                                "\t\t\t\t -phyType $val(netif) \\" + "\n" +
                                "\t\t\t\t -topoInstance $topo  \\" + "\n" +
                                "\t\t\t\t -channelType $val(chan) \\" + "\n" +
                                "\t\t\t\t -wiredRouting OFF \\" + "\n" +
                                "\t\t\t\t -agentTrace ON  \\" + "\n" +
                                "\t\t\t\t -routerTrace ON \\" + "\n" +
                                "\t\t\t\t -macTrace OFF \\" + "\n" +
                                "\t\t\t\t -movementTrace OFF" + "\n\n";

            content = content + "#============================" + "\n\n";

            content = content + "#  Thiet lap BS va cac mobile node" + "\n" +
                                "set BS(0) [$ns_ node 0]" + "\n" +
                                "$BS(0) random-motion 0" + "\n" +
                                "set p_BS [new Agent/Protoname [$BS(0) node-addr]]" + "\n" +
                                "$ns_ attach-agent $BS(0) $p_BS" + "\n" +
                                "$p_BS setAttribute 1000" + "\n" +
                                "$p_BS KhoiTaoDB_BS " + "\"" + listDLPath1[1] + "\\\\BS_data.txt" + "\"" + "\n" +
                                "$p_BS KhoiTaoHLC_BS " + "\"" + listDLPath1[3] + "\"" + "\n" +
                                "$p_BS pathOutPut " + "\"" + listDLPath1[2] + "\\\\" + "\"" + "\n" +
                                "$p_BS KhoiTaoIDchange_BS " + "\"" + listDLPath1[4] + "\"" + "\n\n";

            content = content + "#============================" + "\n\n";

            content = content + "for {set i 1} {$i <= $val(nn) } {incr i} {" + "\n" +
                                "\t\tset node_($i) [$ns_ node $i]" + "\n" +
                                "\t\t$node_($i) random-motion 0" + "\n" +
                                "\t\tset p_($i) [new Agent/Protoname [$node_($i) node-addr]]" + "\n" +
                                "\t\t$ns_ attach-agent $node_($i) $p_($i)" + "\n" +
                                "\t\t$ns_ connect $p_($i) $p_BS" + "\n" +
                                "\t\t#Khoi tao gia tri: argv[1]: cacheSite; argv[2]:  Label" + "\n" +
                                "\t\t$p_($i) setAttribute 100" + "\n" +
                                "\t\t$p_($i) pathOutPut " + "\"" + listDLPath1[2] + "\\\\" + "\"" + "\n\n" +
                                "\t\t#Khoi tao du lieu cho moi MU" + "\n" +
                                "\t\tset filename " + "\"" + listDLPath1[1] + "\\\\MU" + "\"" + "\n" +
                                "\t\tappend filename $i" + "\n" +
                                "\t\tappend filename " + "\"" + "_data.txt" + "\"" + "\n" +
                                "\t\t$p_($i) KhoiTaoLD_MU $filename" + "\n" +                                
                                "}" + "\n\n";

            content = content + "for {set i 1} {$i < $val(nn)} {incr i} {" + "\n" +
                                "\t\tset kq [expr $val(nn)-1]" + "\n" +
                                "\t\tif {$i == $kq} {" + "\n" +
                                "\t\tbreak" + "\n" +
                                "\t\t}" + "\n" +
                                "\t\tfor {set j [expr $i +1]} {$j <= $val(nn)} {incr j} {" + "\n" +
                                "\t\t\t$ns_ connect $p_($i) $p_($j)" + "\n" +
                                "\t}" + "\n" + 
                                "}" + "\n\n";

            content = content + "#============================" + "\n\n";
            // Thiet lap toa do MU
            content = content + "# Thiet lap toa do cho cac mobile node trong khong gian 2 chieu" + "\n";

            for (int i = 0; i < listOfNode.Count; i++)
            {
                Init.MUNOde m = listOfNode[i];
                content = content + "$" + m.id + " set X_ " + String.Format("{0:0.0}", m.x) + "\n";
                content = content + "$" + m.id + " set Y_ " + String.Format("{0:0.0}", m.y) + "\n";
                content = content + "$" + m.id + " set Z_ 0.0 " + "\n\n";
            }
            content = content + "\n";
            content = content + "#============================" + "\n\n";
            content = content + "#========================================================" + "\n" +
                              "#MU vung tim ds neighbor" + "\n" +
                              "for {set i 1} {$i <= $val(nn)} {incr i} {" + "\n" +
                              "\t$ns_ at [expr $i*3] " + "\"" + "$p_($i) MUfindNeighbors" + "\"" + "\n" +
                              "}" + "\n\n";
            content = content + "$ns_ at 200.0 " + "\"" + "$p_BS BroadcastHLC" + "\"" + "\n\n";
            content = content + "#=====================================================" + "\n"
                              + "# BS broadcast Thong tin cap nhat IR" + "\n\n";  

            // ================= Random mat ket noi ==================
            List<int> MUMatketnoi = new List<int>();
            List<int> thoiGianMatKetnoi = new List<int>();
            // Random MU mat ket noi
            for (int i = 0; i < soMUMatKetNoi; i++)
            {
                int idMU = 1;
                    
                do
                {
                    idMU   = rand.Next(1, NumOfNode);
                }
                while(CheckInList( MUMatketnoi, idMU) == true);                 
                MUMatketnoi.Add(idMU);
            }
            // Random thoi gian mat ket noi
            for (int i = 0; i < soMUMatKetNoi; i++)
            {
                int start = rand.Next(1, 20);
                int dur = rand.Next(1, 15);
                int end = start + dur;
                content = content + "$ns_ at 400.0 " + "\"" + "$p_(" +  MUMatketnoi[i].ToString() + ") setDisconnect " + start.ToString() + " " + end.ToString() + "\"" + "\n";
            }
            content = content + "\n";

            //========================================

                content = content + "$ns_ at  400.0 " + "\"" + "$p_BS BroadcastIR" + "\"" + "\n\n";
            // Run
            content = content + "for {set i 1} {$i <= $val(nn) } {incr i} {" + "\n" +
                                "\t$ns_ at $val(stop) " + "\"" + "$node_($i) reset" + "\"" + "\n" +
                                "\t$ns_ at $val(stop) " + "\"" + "$p_($i) StopTrace_Client" + "\"" + "\n" +
                                "}" + "\n" +
                                "$ns_ at $val(stop).0001 " + "\"" + "$BS(0) reset" + "\"" + "\n" +
                                "$ns_ at $val(stop).0001 " + "\"" + "$p_BS StopTrace" + "\"" + "\n\n" +
                                "$ns_ at $val(stop).0002 " + "\"" + "stop" + "\"" + "\n" +
                                "$ns_ at $val(stop).0003 " + "\"" + "puts \\" + "\"" + "FINISH...\\" + "\"" + "; $ns_ halt" + "\"" + "\n" +
                                "proc stop {} {" + "\n" +
                                "}" + "\n" +
                                "puts " + "\"" + "Starting Simulation..." + "\"" + "\n" +
                                "$ns_ run" + "\n";

            /*
            SaveFileDialog DialogSave = new SaveFileDialog();
            DialogSave.DefaultExt = "tcl";
            DialogSave.Filter = "TCL file (*.tcl)|*.tcl";
            DialogSave.AddExtension = false;
            DialogSave.RestoreDirectory = true;
            DialogSave.Title = "Bạn muốn lưu file ở đâu?";
            DialogSave.InitialDirectory = @"C:/cygwin/usr/local/ns-allinone-2.31/ns-2.31";

            // Show the dialog and process the result
            if (DialogSave.ShowDialog() == DialogResult.OK)
            {
                string writeFile = DialogSave.FileName;
                CPara.ClearFile(writeFile);
                CPara.WriteFile(writeFile, content);

            }
            DialogSave.Dispose();
            DialogSave = null;
            */

            string TCLPath = listDLPath[0] + "\\mytcl.tcl";
            //MessageBox.Show(TCLPath);
            CPara.ClearFile(TCLPath);
            CPara.WriteFile(TCLPath, content);
            MessageBox.Show("Ghi file TCL thành công ! ");
            // =======================================
        }

    }
}
